#include <iostream>
#include <windows.h>
#include <conio.h>
#include <fstream>
#include <ctime>
#include <iomanip>
using namespace std;

const int WIDTH = 60;
const int HEIGHT = 20;
int score = 0;
int max_score = 0;
int level = 5;
bool gameover = false;

struct Snake {
    int x[500], y[500];
    int length;
    char direction;
    int oldTailX;
    int oldTailY;
} snake;

struct Food {
    int x, y;
} food;

// 速度计算函数
int getSpeed() { return 200 - (level - 1) * 20; }

void gotoXY(int x, int y) {
    COORD coord = { (SHORT)x, (SHORT)y };
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void setColor(int color) {
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}

void readMaxScore() {
    ifstream file("save.txt");
    if (file) file >> max_score;
    file.close();
}

void saveMaxScore() {
    ofstream file("save.txt");
    file << max_score;
    file.close();
}

void initSnake() {
    snake.length = 3;
    snake.direction = 'R';
    for (int i = 0; i < snake.length; i++) {
        snake.x[i] = 24 - i * 2;
        snake.y[i] = 5;
    }
    snake.oldTailX = snake.x[snake.length - 1];
    snake.oldTailY = snake.y[snake.length - 1];
}

void createFood() {
    bool valid;
    do {
        valid = true;
        food.x = 2 + 2 * (rand() % (WIDTH / 2 - 2));
        food.y = 1 + rand() % (HEIGHT - 2);
        for (int i = 0; i < snake.length; i++) {
            if (food.x == snake.x[i] && food.y == snake.y[i]) {
                valid = false;
                break;
            }
        }
    } while (!valid);
    setColor(12); // 红色食物
    gotoXY(food.x, food.y);
    cout << "★";
}

void drawMap() {
    setColor(11);
    gotoXY(0, 0); cout << "╔";
    gotoXY(WIDTH - 1, 0); cout << "╗";
    gotoXY(0, HEIGHT - 1); cout << "╚";
    gotoXY(WIDTH - 1, HEIGHT - 1); cout << "╝";
    for (int x = 1; x < WIDTH - 1; x++) {
        gotoXY(x, 0); cout << "═";
        gotoXY(x, HEIGHT - 1); cout << "═";
    }
    for (int y = 1; y < HEIGHT - 1; y++) {
        gotoXY(0, y); cout << "║";
        gotoXY(WIDTH - 1, y); cout << "║";
    }
}

void moveSnake() {
    gotoXY(snake.oldTailX, snake.oldTailY);
    cout << "  ";
    if (snake.oldTailX == WIDTH - 2) {
        gotoXY(WIDTH - 1, snake.oldTailY);
        setColor(11);
        cout << "║";
    }
    for (int i = snake.length - 1; i > 0; i--) {
        snake.x[i] = snake.x[i - 1];
        snake.y[i] = snake.y[i - 1];
    }
    switch (snake.direction) {
    case 'U': snake.y[0]--; break;
    case 'D': snake.y[0]++; break;
    case 'L': snake.x[0] -= 2; break;
    case 'R': snake.x[0] += 2; break;
    }
    if (snake.x[0] == food.x && snake.y[0] == food.y) {
        snake.length++;
        snake.x[snake.length - 1] = snake.oldTailX;
        snake.y[snake.length - 1] = snake.oldTailY;
        score += level * 2;
        createFood();
    }
    snake.oldTailX = snake.x[snake.length - 1];
    snake.oldTailY = snake.y[snake.length - 1];
}

void drawSnake() {
    setColor(10); // 绿色蛇头
    gotoXY(snake.x[0], snake.y[0]);
    cout << "●";
    setColor(12); // 红色蛇身
    for (int i = 1; i < snake.length; i++) {
        gotoXY(snake.x[i], snake.y[i]);
        cout << "■";
    }
}

bool checkCollision() {
    if (snake.x[0] <= 0 || snake.x[0] >= WIDTH - 1 ||
        snake.y[0] <= 0 || snake.y[0] >= HEIGHT - 1)
        return true;
    for (int i = 1; i < snake.length; i++) {
        if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
            return true;
    }
    return false;
}

void handleInput() {
    if (_kbhit()) {
        int key = _getch();
        if (key == 0 || key == 0xE0) {
            key = _getch();
            switch (key) {
            case 59: if (level < 10) level++; break;  // F1
            case 60: if (level > 1) level--; break;   // F2
            }
        }
        else {
            switch (tolower(key)) {
            case 'w': if (snake.direction != 'D') snake.direction = 'U'; break;
            case 's': if (snake.direction != 'U') snake.direction = 'D'; break;
            case 'a': if (snake.direction != 'R') snake.direction = 'L'; break;
            case 'd': if (snake.direction != 'L') snake.direction = 'R'; break;
            case 27: gameover = true; break;  // ESC
            }
        }
    }
}

void showInfo() {
    setColor(7);
    gotoXY(WIDTH + 2, 2);  cout << "当前得分: " << score;
    gotoXY(WIDTH + 2, 4);  cout << "历史最高: " << max_score;
    gotoXY(WIDTH + 2, 6);  cout << "速度等级: " << level << "级  ";
    gotoXY(WIDTH + 2, 8);  cout << "单食物得分: " << level * 2 << "分";
    gotoXY(WIDTH + 2, 10); cout << "WASD键控制移动";
    gotoXY(WIDTH + 2, 12); cout << "F1加速 F2减速";
    gotoXY(WIDTH + 2, 14); cout << "ESC退出游戏";
}

void showGameOver() {
    system("cls");
    setColor(12);
    
    // 绘制游戏结束界面
    cout << "\n\n  ╔══════════════════════════════════════════════╗\n";
    cout << "  ║                游 戏 结 束                   ║\n";
    cout << "  ╠══════════════════════════════════════════════╣\n";
    cout << "  ║ 当前得分: " << setw(34) << left << score << "║\n";
    cout << "  ║ 历史最高: " << setw(34) << max_score << "║\n";
    
    if(score > max_score) {
        setColor(10);
        cout << "  ║ ★★★ 创纪录啦！最高分被你刷新啦 ★★★  ║\n";
    } else {
        setColor(8);
        cout << "  ║ 继续努力吧~你离最高分还差: " << setw(16) << (max_score - score) << "║\n";
    }
    
    setColor(12);
    cout << "  ╠══════════════════════════════════════════════╣\n";
    cout << "  ║                                              ║\n";
    cout << "  ║   ";
    setColor(12); cout << "★ 1.重玩一局"; 
    setColor(7); cout << "     ";
    setColor(12); cout << "★ 2.退出游戏"; 
    setColor(7); cout << "   ║\n";
    cout << "  ║                                              ║\n";
    cout << "  ╚══════════════════════════════════════════════╝\n";
    setColor(7);
    cout << "\n        请输入选择（1/2）：";
}

void gameLoop() {
    system("cls");
    readMaxScore();
    int old_max = max_score; // 保存旧记录用于比较
    drawMap();
    initSnake();
    createFood();
    level = 5;

    while (!gameover) {
        drawSnake();
        showInfo();
        handleInput();
        moveSnake();
        gameover = checkCollision();
        Sleep(getSpeed());
    }

    if (score > max_score) {
        max_score = score;
        saveMaxScore();
    }
    
    showGameOver();
    
    // 处理游戏结束后的输入
    while (true) {
        char input = _getch();
        if (input == '1') {
            score = 0;
            gameover = false;
            gameLoop();
            return;
        } else if (input == '2') {
            exit(0);
        } else {
            setColor(12);
            cout << "\n        输入错误，请重新输入：";
        }
    }
}

void showRules() {
    system("cls");
    setColor(11);
    cout << "╔══════════════════════════════════════════════╗\n";
    cout << "║                游 戏 规 则                  ║\n";
    cout << "╠══════════════════════════════════════════════╣\n";
    setColor(7);
    cout << "║ 1. 使用WASD键控制蛇的移动方向               ║\n";
    cout << "║ 2. 吃掉★食物增长身体并得分                 ║\n";
    cout << "║ 3. F1加速/F2减速（速度等级1-10）            ║\n";
    cout << "║ 4. 速度越快，单食物得分越高（等级×2）       ║\n";
    cout << "║ 5. 碰撞墙壁或自己身体游戏结束               ║\n";
    cout << "║ 6. ESC键可随时退出游戏                     ║\n";
    setColor(11);
    cout << "╚══════════════════════════════════════════════╝\n";
    setColor(14);
    cout << "\n        按任意键返回主菜单...";
    _getch();
}

void drawMainMenu(int selected) {
    system("cls");
    setColor(11);
    
    // 绘制标题艺术字
    cout << "  ████████  █████  ███    ██  ██████  ███████ ██   ██ \n";
    cout << "     ██    ██   ██ ████   ██ ██      ██      ██  ██  \n";
    cout << "     ██    ███████ ██ ██  ██ ██      █████   █████   \n";
    cout << "     ██    ██   ██ ██  ██ ██ ██      ██      ██  ██  \n";
    cout << "     ██    ██   ██ ██   ████  ██████ ███████ ██   ██ \n\n";

    // 绘制选项框
    auto drawOption = [](int color, string text, bool isSelected) {
        setColor(color);
        cout << (isSelected ? "  ? " : "    ") << text << endl;
    };

    setColor(11);
    cout << "╔══════════════════════════════════════════════╗\n";
    drawOption(selected == 0 ? 10 : 7, "1. 开始游戏", selected == 0);
    drawOption(selected == 1 ? 10 : 7, "2. 游戏规则", selected == 1);
    drawOption(selected == 2 ? 10 : 7, "3. 退出游戏", selected == 2);
    cout << "╚══════════════════════════════════════════════╝\n";
    
    setColor(8);
    cout << "\n 使用 ↑ ↓ 键选择，ENTER 键确认\n";
}

int main() {
    // 设置控制台编码为UTF-8
    system("chcp 65001 > nul");
    system("mode con cols=90 lines=30");
    CONSOLE_CURSOR_INFO cursor = { 1, FALSE };
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor);
    srand(static_cast<unsigned>(time(0)));

    int selected = 0;
    while (true) {
        drawMainMenu(selected);

        int key = _getch();
        if (key == 0xE0) {
            key = _getch();
            switch (key) {
            case 72: if (selected > 0) selected--; break;    // 上箭头
            case 80: if (selected < 2) selected++; break;    // 下箭头
            }
        }
        else if (key == 13) {  // 回车键
            switch (selected) {
            case 0:  // 开始游戏
                gameLoop();
                break;
            case 1:  // 游戏规则
                showRules();
                break;
            case 2:  // 退出游戏
                return 0;
            }
        }
    }
    return 0;
}